﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Sausage.Common;
using Sausage.Web.DataModel;
using Sausage.Web.Models;

namespace Sausage.Web.Domain
{
    public class ConstructionHelper 
    {
        public static IEnumerable<TreeNodeData> QueryConstructionTree()
        {
            using (var context = new SausageEntities())
            {
                return GetChildren(null, context.Construction.ToList());
            }
        }

        private static IEnumerable<TreeNodeData> GetChildren(Guid? parentID, IEnumerable<Construction> constructionList)
        {
            var children = from construction in constructionList
                           where construction.ParentID == parentID
                           orderby construction.ConstructionName
                           select
                               new TreeNodeData
                               {
                                   id = construction.ConstructionID,
                                   expanded = false,
                                   leaf = construction.IsLeaf,
                                   name = construction.ConstructionName,
                                   parentID = construction.ParentID,
                                   unit = construction.Unit,
                                   pinyin = construction.ConstructionPinYin,
                                   data = GetChildren(construction.ConstructionID, constructionList)
                               };

            return children;
        }

        public static Construction GetConstructionByID(Guid id)
        {
            using (var context = new SausageEntities())
            {
                return context.Construction.FirstOrDefault(construction => construction.ConstructionID == id);
            }
        }

        public static DeleteResult DeleteConstruction(Guid id)
        {
            using (var context = new SausageEntities())
            {
                var construction = context.Construction.FirstOrDefault(item => item.ConstructionID == id);
                if (construction == null || !construction.IsLeaf)
                    return DeleteResult.Ok;


                //just delete the leaf node.
                if (construction.ParentID.HasValue)
                {
                    var brothers = context.Construction.Where(item => item.ParentID == construction.ParentID).ToList();
                    if (brothers.Count <= 1)
                    {
                        var parent = context.Construction.FirstOrDefault(item => item.ConstructionID == construction.ParentID.Value);
                        if (parent != null)
                            parent.IsLeaf = true;
                    }
                }

                context.ObjectStateManager.ChangeObjectState(construction, EntityState.Deleted);
                try
                {
                    context.SaveChanges();
                }
                catch(UpdateException)
                {
                    return DeleteResult.UsingError;
                }
                return DeleteResult.Ok;
            }
        }

        public static void UpdateConstruction(TreeNodeData data)
        {
            using (var context = new SausageEntities())
            {
                var construction = context.Construction.FirstOrDefault(item => item.ConstructionID == data.id);
                if (construction == null)
                    return;

                construction.ConstructionName = data.name;
                construction.ConstructionPinYin = data.pinyin;
                construction.Unit = data.unit;

                context.SaveChanges();
            }
        }

        public static Construction GetConstructionByName(string name)
        {
            using (var context = new SausageEntities())
            {
                return context.Construction.FirstOrDefault(construction => construction.ConstructionName == name);
            }
        }

        public static void CreateConstruction(TreeNodeData data)
        {
            using (var context = new SausageEntities())
            {
                var construction = new Construction();

                construction.ConstructionID = Guid.NewGuid();
                construction.ParentID = data.parentID;
                construction.ConstructionName = data.name;
                construction.ConstructionPinYin = data.pinyin;
                construction.Unit = data.unit;
                construction.TheOrder = 0;
                construction.IsLeaf = true;

                if (data.parentID.HasValue)
                {
                    var parent = context.Construction.FirstOrDefault(item => item.ConstructionID == data.parentID.Value);
                    parent.IsLeaf = false;
                }

                context.AddToConstruction(construction);
                context.SaveChanges();
            }
        }
    }
}
